﻿using System.Collections.Generic;
using System.Linq;
using Yamfinder.Data;

namespace Yamfinder.Service
{
    public class LexicalTable
    {
        public string XAxisFieldname { get; set; }
        public string YAxisFieldname { get; set; }
        public bool XAxisSortIncreasing { get; set; }
        public bool YAxisSortIncreasing { get; set; }

        public long ColumnCount { get; set; }
        public long RowCount { get; set; }

        private readonly LexicalEntry[,] _data;

        public IList<string> ColumnHeaders { get; set; }
        public IList<string> RowHeaders { get; set; }

        public LexicalTable(IList<LexicalEntry> queryResults, LexicalSearchCriteria searchCriteria)
        {
            //Need to sort results based on search criteria
            XAxisFieldname = searchCriteria.XAxisFieldname;
            XAxisSortIncreasing = searchCriteria.XAxisSortIncreasing;
            YAxisFieldname = searchCriteria.YAxisFieldname;
            YAxisSortIncreasing = searchCriteria.YAxisSortIncreasing;

            //Remove values that dont fit the axis
            queryResults = queryResults
                .Where(x => x.Fields.ContainsKey(XAxisFieldname))
                .Where(x => x.Fields.ContainsKey(YAxisFieldname))
                .ToList();

            //Get columns and organise them!
            var columns = queryResults.Select(x => x.Fields[XAxisFieldname]).Distinct();
            columns = XAxisSortIncreasing
                          ? columns.OrderBy(x => x.ToString())
                          : columns.OrderByDescending(x => x.ToString());
            ColumnCount = columns.Count();
            ColumnHeaders = columns.Select(x => x.ToString()).ToList();

            //Get rows and organise them!
            var rows = queryResults.Select(x => x.Fields[YAxisFieldname]).Distinct();
            rows = XAxisSortIncreasing
                          ? rows.OrderBy(x => x.ToString())
                          : rows.OrderByDescending(x => x.ToString());
            RowCount = rows.Count();
            RowHeaders = rows.Select(x => x.ToString()).ToList();

            //initialise the storage
            _data = new LexicalEntry[ColumnCount,RowCount];


            //load data!
            for (int i = 0; i < ColumnCount; i++)
            {
                for (int j = 0; j < RowCount; j++)
                {
                    var colValue = columns.ToList()[i];
                    var rowValue = rows.ToList()[j];

                    //try to find lexical entry
                    var queryFirst = queryResults.Where(x => x.Fields[XAxisFieldname].Equals(colValue));
                    var result = queryFirst.Where(x => x.Fields[YAxisFieldname].Equals(rowValue));

                    if (result.Count() > 0)
                        this[i, j] = result.First();
                }
            }

        }

        public LexicalEntry this[int x, int y]
        {
            get { return _data[x,y]; }
            set { _data[x,y] = value; }
        }
    }
}
